package javabasics;


public class TestEquals {
    /**
     * 1. 基本数据类型
     * java的基本数据类型，也称为原始的数据类型。它们分别是：
     * byte, short, char, int, long, float, double, boolean .
     * 基本数据类型进行 “==” 比较时，比较的是 它们的值 是否相同。
     * 对于基本类型而言，它们没有 equals() 方法，大家别上当啊。
     * */
    public void test$$(){//测试 ==
        int a = 10;
        int b = 10;
        System.out.println(" (a == b) = " + (a == b));
    }

    /**
     * 当 两个对象使用 “==” 进行比较时，比较的是它们在 内存中存放的地址。
     * 也就是说，除非是 同一个new() 出来的两个对象(内存地址相同)， 否则比较的结果都是false
     *
     * 调用equals() 方法时，也仍然是比较两个对象 是否指向同一块内存空间
     * */
    public static void main(String args[]) {
        Worker worker1 = new Worker();
        //worker2 是 worker1 的引用，同指向一个内存空间。
        Worker worker2 = worker1;
        /**
         * 输出的结果：
         * (worker1 == worker2) : true
         * -------------------------
         * (worker3 == worker4) ： false*/
        System.out.println("(worker1 == worker2) : " + (worker1 == worker2));

        System.out.println("-------------------------");

        Worker worker3 = new Worker();
        //worker3 与 worker4 都是调用new 产生的对象，不指向同一个内存空间。
        Worker worker4 = new Worker();
        System.out.println("(worker3 == worker4) ： " + (worker3 == worker4));

        //关于equals的测试
        /**
        * 运行结果如下：
        * worker1.equals(worker2) : true
        * -------------------------
        * worker3.equals(worker4) ： false
        * */
        Worker worker11 = new Worker();
        //worker22 是 worker11的引用，同指向一个内存空间。
        Worker worker22 = worker1;
        System.out.println("worker1.equals(worker2) : " + worker11.equals(worker22));

        System.out.println("-------------------------");

        Worker worker33 = new Worker();
        //worker33 与 worker44 都是调用new 产生的对象，不指向同一个内存空间。
        Worker worker44 = new Worker();
        System.out.println("worker33.equals(worker44) ： " + worker33.equals(worker44));
        /**
         * equals() 方法比较的是 两个对象的内容嘛？ 没错，默认的约定是这样的。对于我们自己写的类，
         * 如果想要达到这个效果，那么就要重写 equals()方法了。
         * */

        /**
         * 3. 怪异的String
         *
         * 上文说了，String类重写了 equals() 方法，当调用equals()方法比较两个String对象时，比较的是其内容，那 怪异二字 从何而来呢？
         * 且看下面代码：
         *
         * public class Main2 {
         *     public static void main(String args[]) {
         *         String s1 = "hello world";
         *         String s2 = "hello world";
         *
         *         System.out.println("s1.equals(s2) : " + s1.equals(s2));
         *         System.out.println("(s1 == s2) : " + (s1 == s2));
         *
         *     }
         * }
         *
         * 运行结果如下：
         * s1.equals(s2) : true
         * (s1 == s2) : true
         * 输出结果说明，s1 与 s2 同指向一个 String对象。
         *
         * 先不着急，我们再修改一下上面代码：
         *
         * public class Main3 {
         *     public static void main(String args[]) {
         *
         *         String s1 = "hello world";
         *         String s2 = new String("hello world");
         *
         *         System.out.println("s1.equals(s2) : " + s1.equals(s2));
         *         System.out.println("(s1 == s2) : " + (s1 == s2));
         *
         *     }
         * }
         *
         * 运行结果：
         * s1.equals(s2) : true
         * (s1 == s2) : false
         * 输出结果说明，s1 与 s2 不属于同一个String对象。
         *
         * 为什么出现上面这个怪异的问题？
         * 原来，程序在运行的时候会创建一个字符串缓冲池。
         * 当使用  String s2 = “hello world” ，
         * 这样的表达是创建字符串的时候，程序首先会在这个String缓冲池中寻找相同值的对象，在第一个程序中，s1先被放到了池中，所以在s2被创建的时候，程序找到了具有相同值的 s1，将s2引用  s1所引用的 对象 “hello world”。
         * 第二段程序中，使用了 new 操作符，它明白的告诉程序：”我要一个新的！不要旧的！”于是一个新的”hello world” Sting对象被创建在内存中。它们的值相同，但是内存地址不同，一个在池中游泳，另一个在岸边休息。
         *
         * 事情还没完，在看看下面这个例子。
         *
         * public class Main4 {
         *     public static void main(String[] args) {
         *         String s1 = "hello world";
         *         String s2 = new String("hello world");
         *
         *         s2 = s2.intern();
         *
         *         System.out.println("s1.equals(s2) : " + s1.equals(s2));
         *         System.out.println("(s1 == s2) : " + (s1 == s2));
         *     }
         * }
         *
         * 运行结果如下：
         * s1.equals(s2) : true
         * (s1 == s2) : true
         *
         * 怎么会这样？？？
         * 原来，java.lang.String的intern()方法 ，例如 “abc”.intern()方法的返回值还是字符串”abc”，
         * 表面上看起来好像这个方法没什么用处。但实际上，它做了个小动作：检查字符串池里是否存在”abc”
         * 这么一个字符串，如果存在，就返回池里的字符串；如果不存在，该方法会 把”abc”添加到字符串池中，
         * 然后再返回它的引用。
         * */

    }
}

class Worker {

    private String name;
    private double salary;

    public Worker() {
        this.name = "echo";
        this.salary = 0.0;
    }
    public Worker(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    //重写了Object类的 equals() 方法
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Worker other = (Worker) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (Double.doubleToLongBits(salary) != Double
                .doubleToLongBits(other.salary))
            return false;
        return true;
    }
}


